<?php

/**
 * Created by PhpStorm.
 * User: chenhong
 * Date: 17/2/16
 * Time: 下午2:19
 */
include 'Curl.php';

class Package
{
    private static $path;

    private static $pdo;

    public static function parseParam( $data, $pdo )
    {
        print_r($data);
        self::$pdo   = $pdo;
        $notifyUrl   = isset( $data['notify_url'] ) ? $data['notify_url'] : '';
        $trueGameId  = isset( $data['true_game_id'] ) ? $data['true_game_id'] : '';
        $uid         = isset( $data['uid'] ) ? $data['uid'] : '';
        $downloadUrl = isset( $data['download_url'] ) ? $data['download_url'] : '';
        $isPublic    = isset( $data['is_non_public'] ) ? $data['is_non_public'] : '';
        $hotCloudId  = isset( $data['hot_cloud_id'] ) ? $data['hot_cloud_id'] : '';

        return self::init(
            $data['target_apk'],
            $data['dir'],
            $data['channel'],
            $data['new_apk_name'],
            $data['game_id'],
            $notifyUrl,
            $trueGameId,
            $uid, $downloadUrl,
            $isPublic,
            $hotCloudId
        );
    }

    //解包
    private static function unPackage( $targetApk, $dir )
    {
        if ( is_file($targetApk) ) {
            $targetApk = quotemeta($targetApk);
            $targetApk = str_replace(' ', '\\ ', $targetApk);
            $result    = system('sh ' . __DIR__ . '/apktool/apktool d ' . $targetApk . ' -o ' . $dir);
            if ( !$result ) {
                return false;
            } else {
                self::$path = $dir;

                return true;
            }
        }
    }

    //根据渠道重新打包
    public static function init(
        $targetApk, $dir, $channel, $newApkName, $id,
        $notifyUrl = '', $trueGameId = '', $uid = '',
        $downloadUrl = '', $isPublic, $hotCloudId )
    {
        $path        = dirname(dirname(__DIR__));
        $packagePath = $path . '/storage/apkStore/' . $dir;
        $newApkPath  = $path . '/storage/apkStore/' . $newApkName;
        $savePath    = 'storage/apkStore/' . $newApkName;
        $targetApk   = $path . $targetApk;

        try {
            if ( self::unPackage($targetApk, $packagePath) ) {
                self::addChannel($channel, $hotCloudId, $isPublic);
                if ( self::rPackage($newApkPath) ) {
                    //修改打包状态
                    self::signature($newApkPath, $channel, $packagePath);
                    if ( is_file($newApkPath) ) {
                        //打包成功
                        $result = self::$pdo->update([
                            'status',
                            'update_time',
                            'file_path' ],
                            [
                                ':status'      => 3,
                                ':file_path'   => $savePath,
                                ':update_time' => time()
                            ], 'id=' . $id);

                        if ( $notifyUrl ) {
                            if ( $isPublic ) {
                                $result = self::remoteQuery($notifyUrl, [
                                    'url'     => $downloadUrl,
                                    'uid'     => $uid,
                                    'game_id' => $trueGameId,
                                ]);
                            } else {
                                $result = Curl::query([
                                    'url'     => $notifyUrl,
                                    'isPost'  => true,  //post方式
                                    'dataStr' => [
                                        'url'     => $downloadUrl,
                                        'uid'     => $uid,
                                        'game_id' => $trueGameId,
                                    ],
                                ]);
                            }
                        }

                        //通知CDN 加速 zhiyu 登录密码:zhiyu@2233
                        $result = Curl::query([
                            'url'     => 'http://ccm.chinanetcenter.com/ccm/servlet/contReceiver',
                            'isPost'  => false,  //post方式
                            'dataStr' => [
                                'username' => 'zhiyu',
                                'passwd'   => md5('zhiyu' . 'zhiyu@2233' . $downloadUrl),
                                'url'      => $downloadUrl,
                                'isfetch'  => 'Y',
                            ],
                        ]);

                        print_r($result);

                        return true;
                    } else {
                        $result = self::$pdo->update([ 'status' ], [ ':status' => 2 ], 'id=' . $id);

                        return false;
                    }
                }
            }
        } catch ( Exception $e ) {
            file_put_contents(date('ymdHis', time()) . '.log', $e->getMessage());
        }
    }

    private static function deleteDir( $dir )
    {
        //先删除目录下的文件：
        $dh = opendir($dir);
        while ( $file = readdir($dh) ) {
            if ( $file != "." && $file != ".." ) {
                $fullpath = $dir . "/" . $file;
                if ( !is_dir($fullpath) ) {
                    unlink($fullpath);
                } else {
                    self::deleteDir($fullpath);
                }
            }
        }
        closedir($dh);
        //删除当前文件夹：
        if ( rmdir($dir) ) {
            return true;
        } else {
            return false;
        }
    }


    //修改渠道 ==
    private static function addChannel( $channel, $hotCloudId, $isPublic )
    {
        $filename = self::$path . '/assets/sdk_res/config.properties';
        $handel   = fopen($filename, 'a+');
        $files    = file($filename);
        foreach ( $files as $key => $file ) {
            $arr        = explode('=', $file);
            $channelKey = $arr[0];
            if ( in_array($channelKey, [ 'ChannelCode', 'ReyunKey', 'IsFromZhiYu', 'SKey' ]) ) {
                unset( $files[ $key ] );
                file_put_contents($filename, join('', $files));
            }
        }
        fwrite($handel, 'ChannelCode=' . $channel . PHP_EOL);
        fwrite($handel, 'ReyunKey=' . $hotCloudId . PHP_EOL);
        fwrite($handel, 'IsFromZhiYu=' . $isPublic . PHP_EOL);
        fwrite($handel, 'SKey=1' . PHP_EOL); 
        fclose($handel);
    }

    //重新打包
    private static function rPackage( $newApkName )
    {
        $result = system('sh ' . __DIR__ . '/apktool/apktool b ' . self::$path . ' -o ' . $newApkName);
        if ( !$result ) {
            return false;
        } else {
            return true;
        }
    }

    //签名
    private static function signature( $newApkName, $channel, $dir )
    {
        $result = system('jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore ' . __DIR__ . '/teststore.jks -storepass 123456 ' . $newApkName . ' icesslkey');
        //删除解包文件
        self::deleteDir($dir);
    }


    public static function remoteQuery( $url, $value = [ ] )
    {
        $value ['timestamp'] = time();
        $params              = [
            'url'     => $url,
            'isPost'  => true,  //post方式
            'dataStr' => [ //参数
                           'sign'      => self::makeSign($value),
                           'timestamp' => time(),
            ]
        ];

        foreach ( $value as $filed => $item ) {
            $params['dataStr'][ $filed ] = $item;
        }

        return Curl::query($params);
    }

    /**
     * 生成签名
     *
     * @param array $not_sign_param 不参与加密的参数名
     *
     * @return string                   签名，本函数不覆盖sign成员变量
     */
    public static function makeSign( $params, $not_sign_param = [ ] )
    {
        // 签名步骤一：按字典序排序参数(对关联数组按照键名进行升序排序)
        ksort($params);
        $string = self::toUrlParams($params, $not_sign_param);
        // 签名步骤二：在string后加入KEY
        $string = $string . "appkey" . '6e70865e4d831f4503e69f4a5b754fd6';
        // 签名步骤三：MD5加密
        $string = md5($string);
        // 签名步骤四：所有字符转为大写
        $result = strtoupper($string);

        return $result;
    }

    /**
     * 格式化参数格式化成url参数
     *
     * @param array $not_sign_param 不参与加密的参数名
     *
     * @return string                   返回拼接后的参数
     */
    public static function toUrlParams( $params, $not_sign_param = [ ] )
    {
        $buff = "";
        foreach ( $params as $k => $v ) {
            if ( !in_array('sign', $not_sign_param) ) {
                array_push($not_sign_param, 'sign');
            }
            if ( !in_array($k, $not_sign_param) && $v != "" && !is_array($v) ) {
                $buff .= $k . $v;
            }
        }

        return $buff;
    }
}